
package cz.czu.pef.DataModelling.utils;

import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.springframework.dao.CleanupFailureDataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;

// Source: http://forum.springsource.org/showthread.php?t=76488&page=4
/* Configure in web.xml:
 <filter>
    <filter-name>HibernateOpenSessionFilter</filter-name>
    <filter-class>cz.czu.pef.DataModelling.dao.impl.HibernateOpenSessionFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>HibernateOpenSessionFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
*/
/* Result:
java.lang.IllegalStateException: Context attribute is not of type WebApplicationContext: Root WebApplicationContext: startup date [Tue Jan 04 22:34:26 CET 2011]; root of context hierarchy
	org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:124)
	org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:99)
	org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:82)
	org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.lookupSessionFactory(OpenSessionInViewFilter.java:241)
	org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.lookupSessionFactory(OpenSessionInViewFilter.java:227)
	org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:171)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
	org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:163)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
 */
public class HibernateOpenSessionFilter extends OpenSessionInViewFilter
{

	@Override
	protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException
	{
		Session session = SessionFactoryUtils.getSession(sessionFactory, true /*allowCreate*/);
		session.setFlushMode(FlushMode.AUTO);
		return session;
	}

	@Override
	protected void closeSession(Session session, SessionFactory sessionFactory)
	{
		try
		{
			try
			{
				if (session != null && session.isOpen() && session.isConnected())
				{
					session.flush();
				}
			}
			catch (HibernateException e)
			{
				throw new CleanupFailureDataAccessException("Failed to flush session before close: " + e.getMessage(), e);
			}
		}
		finally
		{
			super.closeSession(session, sessionFactory);
		}
	}
}